package modulo3.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author jjsanche
 */
public class Recordatorios implements Serializable {
    private static final Recordatorios singleton = new Recordatorios();
    
    private List<Recordatorio> pendientes;
    private List<Recordatorio> terminados;

    private Recordatorios() {
        pendientes = new ArrayList();
        terminados = new ArrayList();
    }
    
//    private void writeObject(ObjectOutputStream oos) throws IOException {
//        oos.defaultWriteObject();
//        
//        for (Recordatorio rec: pendientes) {
//            oos.writeObject(rec);
//        }
//        
//        for (Recordatorio rec: terminados) {
//            oos.writeObject(rec);
//        }
//    }
//    
//    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
//        ois.defaultReadObject();
//        
//        pendientes = new ArrayList();
//        terminados = new ArrayList();
//        List<Recordatorio> target = pendientes;
//        
//        boolean revisarTipo = true;
//        
//        Recordatorio recordatorio;
//        
//        while ((recordatorio = (Recordatorio) ois.readObject()) != null) {
//            if (revisarTipo) {
//                if (recordatorio.getFechaDeTermino() != null) {
//                    target = terminados;
//                }
//            }
//            
//            target.add(recordatorio);
//        }
//    }
    
    public static Recordatorios getInstance() {
        return singleton;
    }
    
    public void agregarRecordatorio(String descripcion, Prioridad prioridad) {
        if (prioridad == null) {
            pendientes.add(new Recordatorio(descripcion));
        } else {
            pendientes.add(new Recordatorio(descripcion, prioridad));
        }
    }

    public void eliminarRecordatorio(TipoRecordatorio tipo, int indice) {
        if (tipo == TipoRecordatorio.PENDIENTE) {
            pendientes.remove(indice);
        } else if (tipo == TipoRecordatorio.TERMINADO) {
            terminados.remove(indice);
        }
    }

    public void eliminarTodos(TipoRecordatorio tipo) {
        if (tipo == TipoRecordatorio.PENDIENTE) {
            pendientes.clear();
        } else if (tipo == TipoRecordatorio.TERMINADO) {
            terminados.clear();
        }
    }

    public void modificarRecordatorio(TipoRecordatorio tipo, int indice,
            String descripcion, Prioridad prioridad) {

        Recordatorio recordatorio = getRecordatorio(tipo, indice);
        setPropiedadesRecordatorio(recordatorio, descripcion, prioridad);
    }

    private Recordatorio getRecordatorio(TipoRecordatorio tipo, int indice) {
        if (tipo == TipoRecordatorio.PENDIENTE) {
            return pendientes.get(indice);
        } else if (tipo == TipoRecordatorio.TERMINADO) {
            return terminados.get(indice);
        }

        return null;
    }

    private void setPropiedadesRecordatorio(Recordatorio recordatorio, String descripcion, Prioridad prioridad) {
        recordatorio.setDescripcion(descripcion);
        recordatorio.setPrioridad(prioridad);
    }

    public void terminarRecordatorio(int indice) {
        Recordatorio recordatorio = pendientes.remove(indice);
        recordatorio.setTerminado(true);
        terminados.add(recordatorio);
    }

    public void ordenarRecordatorios(TipoRecordatorio tipo, AtributoRecordatorio atributo) {
        if (tipo == TipoRecordatorio.PENDIENTE && atributo == AtributoRecordatorio.FECHA_TERMINO) {
            throw new IllegalArgumentException("No se puede ordenar recordatorios pendientes por fecha de termino");
        } else if (tipo == TipoRecordatorio.TERMINADO && atributo == AtributoRecordatorio.PRIORIDAD) {
            throw new IllegalArgumentException("No tiene sentido ordenar recordatorios finalizados por prioridad");
        }

        Collections.sort(pendientes, atributo.getComparator());
    }

    public List<Recordatorio> filtrarRecordatorios(TipoRecordatorio tipo, AtributoRecordatorio atributo, Object valor) {
        if (tipo == TipoRecordatorio.PENDIENTE && atributo == AtributoRecordatorio.FECHA_TERMINO) {
            throw new IllegalArgumentException("No se puede ordenar recordatorios pendientes por fecha de termino");
        } else if (tipo == TipoRecordatorio.TERMINADO && atributo == AtributoRecordatorio.PRIORIDAD) {
            throw new IllegalArgumentException("No tiene sentido ordenar recordatorios finalizados por prioridad");
        }

        List<Recordatorio> recordatorios = tipo == TipoRecordatorio.PENDIENTE ? pendientes : terminados;
        List<Recordatorio> filtrados = new ArrayList<>();
        Comparator comparator = atributo.getComparator();
        Recordatorio recordatorioMuestra = new Recordatorio(valor, atributo);
        
        for (Recordatorio recordatorio : recordatorios) {
            if (Objects.compare(recordatorio, recordatorioMuestra, comparator) == 0) {
                filtrados.add(recordatorio);
            }
        }
        return filtrados;
    }
    
    public List<Recordatorio> getRecordatorios(TipoRecordatorio tipo) {
        return tipo == TipoRecordatorio.PENDIENTE ? pendientes : terminados;
    }
}
